<template>
  <div class="msg-box" @mousewheel.stop="mousewheel">
    <div class="add-box w-card">
      <div class="title-box">
        <span class="title-text">新建消息</span>
      </div>
      <div class="add-content" :style="{'height':tableHeight+'px'}" @scroll.stop="addMsgScroll">
        <el-form ref="dialogFormRef" :model="dialogForm" :rules="dialogFormRules">
          <el-row>
            <el-col :span="12">
              <el-form-item label="标题" prop="title">
                <el-input style="width:90%;" v-model="dialogForm.title" placeholder="请输入标题" @keypress.enter="submitHandle" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="失效时间" prop="expireTime">
                <el-date-picker style="width:90% !important" v-model="dialogForm.expireTime" type="datetime"
                  placeholder="请选择失效时间" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="发送对象" prop="messageType">
            <el-radio-group v-model="dialogForm.messageType">
              <el-radio :label="1">全部</el-radio>
              <el-radio :label="2">指定商户</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-row>
            <el-col :span="12">
              <el-form-item label="" prop="shopIds">
                <el-select :disabled="dialogForm.messageType == 1" style="width:90%;" filterable collapse-tags
                  collapse-tags-tooltip :max-collapse-tags="3" v-model="dialogForm.shopIds" multiple placeholder="请选择商户">
                  <el-option v-for="item in shopOptions" :key="item.shopId" :label="item.shopName" :value="item.shopId" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="消息内容" prop="messageContent">
            <Editor ref="editorRef" width="100%" v-model="dialogForm.messageContent" :api-key="apiKey" :init="init" />
          </el-form-item>
        </el-form>
        <el-button type="primary" @click="submitHandle">
          发送消息
        </el-button>
      </div>
    </div>
    <div class="his-box w-card" :class="{'isHid':isHid}">
      <div class="title-box">
        <span class="title-text">历史消息</span>
      </div>
      <div class="his-content" :style="{'height':tableHeight+'px'}" @mousewheel.stop="hisMsgMousewheel"
        @scroll.stop="hisMsgScroll">
        <div class="table-box">
          <div class="table-item" v-for="item in tableData" :key="item" @click="lookDetail(item)">
            <div>
              <el-checkbox v-model="item.isChecked" label="" size="large" @click.stop=""
                @change="(e) => {tableCheckChange(e,item)}" />
            </div>
            <div class="msg-content">
              <div>
                <span>标题：</span>
                <span style="font-weight:bold">{{ item.title || '' }}</span>
                <span
                  :class="'expireType'+item.expireType">{{ item.expireType == 1 ? '未失效' : item.expireType == 0 ? '已失效' : '' }}</span>
              </div>
              <div>
                <span>失效时间：</span>
                <span>{{ item.expireTime ? getDateTime(item.expireTime)[6] : '' }}</span>
                <span style="margin-left:auto;">发送人：</span>
                <span>{{ item.createUserName || '' }}</span>
                <span style="padding:0 10px;">|</span>
                <span>发送时间：</span>
                <span>{{ item.createTime ? getDateTime(item.createTime)[6] : '' }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="his-footer">
        <el-checkbox v-model="isAllChecked" label="全选" size="large" @change="(e) => {allChange(e)}" />
        <el-button style="margin-left:10px;" :disabled="checkList.length == 0" type="primary" @click="moreSXSC(1)">
          批量失效
        </el-button>
        <el-button :disabled="checkList.length == 0" @click="moreSXSC(2)">
          批量删除
        </el-button>
        <el-pagination style="margin-left:auto;" v-model:currentPage="page" v-model:page-size="size"
          :page-sizes="[10, 20, 50, 100]" small :background="true" layout="total, sizes, prev, pager, next, jumper" :total="total"
          @size-change="handleSizeChange" @current-change="handleCurrentChange" />
      </div>
    </div>
    <div class="indicator-box">
      <div class="indicator-item" :class="{'active-indicator':isHid}" @click="isHid = !isHid"></div>
      <div class="indicator-item" :class="{'active-indicator':!isHid}" @click="isHid = !isHid"></div>
    </div>
    <detail-dialog ref="detailDialogRef" />
    <confirm-pass ref="confirmPassRef" @verification="SXSCHandle" />
  </div>
</template>

<script>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import Editor from "@tinymce/tinymce-vue";
import api from './api'
import { getWindowWidthAndHeight, successDeal, warningDeal, getDateTime } from '@/utils/utils';
import detailDialog from './components/detail.vue'
import axios from "axios"
import confirmPass from '@/components/confirmPass.vue'
export default {
  components: {
    Editor,
    detailDialog,
    confirmPass,
  },
  setup() {
    const dialogFormRef = ref(null)
    const editorRef = ref(null)
    const detailDialogRef = ref(null)
    const confirmPassRef = ref(null)

    const validatePass = (rule, value, callback) => {
      if (state.dialogForm.messageType == 2 && (!state.dialogForm.shopIds || (state.dialogForm.shopIds && state.dialogForm.shopIds.length == 0))) {
        callback(new Error('请选择商户'))
      } else {
        callback()
      }
    }

    const state = reactive({
      page: 1,
      size: 10,
      total: 0,
      isAllChecked: false,
      isSXSC: null,
      myScrollTop: 0,
      isHid: true,
      tableHeight: 0,
      dialogForm: {
        messageType: 1,
      },
      tableData: [],
      checkList: [],
      dialogFormRules: {
        title: [
          { required: true, message: '请输入标题', trigger: 'blur' },
        ],
        expireTime: [
          { required: true, message: '请选择失效时间', trigger: 'blur' },
        ],
        messageType: [
          { required: true, message: '请选择发送对象', trigger: 'blur' },
        ],
        shopIds: [
          { required: true, validator: validatePass, trigger: 'blur' },
        ],
        messageContent: [
          { required: true, message: '请输入消息内容', trigger: 'blur' },
        ],
      },
      shopOptions: [],
    })
    const tiny = reactive(
      {
        content: '',
        apiKey: "m2a7guv01wyg6ihiuafs1cgdf0n92imy7zmurgpwa0i1aefb", //https://github.com/tinymce/tinymce-vue/blob/main/src/demo/views/Iframe.vue
        init: {
          language: "zh_CN", //语言类型
          placeholder: "在这里输入文字", //textarea中的提示信息
          min_width: 320,
          min_height: 200,
          height: 400, //注：引入autoresize插件时，此属性失效
          resize: "both", //编辑器宽高是否可变，false-否,true-高可变，'both'-宽高均可，注意引号
          branding: false, //tiny技术支持信息是否显示
          // statusbar: false,  //最下方的元素路径和字数统计那一栏是否显示
          // elementpath: false, //元素路径是否显示

          font_formats:
            "微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;", //字体样式
          plugins:
            "print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave emoticons", //插件配置 axupimgs indent2em
          toolbar: [
            "fullscreen undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | bullist numlist | blockquote subscript superscript removeformat ",
            "styleselect formatselect fontselect fontsizeselect |  table image axupimgs media emoticons charmap hr pagebreak insertdatetime  selectall visualblocks searchreplace | code print preview | indent2em lineheight formatpainter",
          ], //工具栏配置，设为false则隐藏
          // menubar: "file edit my1", //菜单栏配置，设为false则隐藏，不配置则默认显示全部菜单，也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”

          images_upload_url: '/ums/file/upload/img',  //后端处理程序的url，建议直接自定义上传函数image_upload_handler，这个就可以不用了
          // images_upload_base_path: '/demo',  //相对基本路径--关于图片上传建议查看--http://tinymce.ax-z.cn/general/upload-images.php
          paste_data_images: false, //图片是否可粘贴
          //此处为图片上传处理函数
          images_upload_handler: (blobInfo, success, failure) => {
            const myBlob = blobInfo.blob()
            let param = new FormData()  // 创建form对象
            param.append('file', myBlob, Math.random() * 1000000 + 1 + '.jpg')  // 通过append向form对象添加数据
            let config = {
              headers: {
                'Content-Type': 'multipart/form-data',
                token: '',
                Authorization: `'','','',3,20,''`,
                platformHeadType: 'ilinkPlatform',
              }
            }
            axios.post('/ums/file/upload/img', param, config).then(res => {
              if (res.data.code == '200') {
                success(res.data.data.ossUrl)
              } else {
                warningDeal(res.data.msg)
              }
            }).catch(err => {
              console.log(err)
            })
            // 这里用base64的图片形式上传图片,
            // let reader = new FileReader(); //本地预览
            // reader.readAsDataURL(blobInfo.blob());
            // reader.onloadend = function () {
            //   const imgbase64 = reader.result;
            //   success(imgbase64);
            // };
          },

          file_picker_types: "file image media", //file image media分别对应三个类型文件的上传：link插件，image和axupimgs插件，media插件。想屏蔽某个插件的上传就去掉对应的参数
          // 文件上传处理函数
          file_picker_callback: function (callback, value, meta) {
            // 使用案例http://tinymce.ax-z.cn/general/upload-images.php
            // meta.filetype  //根据这个判断点击的是什么file image media

            let filetype; //限制文件的上传类型,需要什么就添加什么的后缀
            if (meta.filetype == "image") {
              filetype = ".jpg, .jpeg, .png, .gif, .ico, .svg";
            } else if (meta.filetype == "media") {
              filetype = ".mp3, .mp4, .avi, .mov";
            } else {
              filetype =
                ".pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4, .jpg, .jpeg, .png, .gif, .ico, .svg";
            }
            let inputElem = document.createElement("input"); //创建文件选择
            inputElem.setAttribute("type", "file");
            inputElem.setAttribute("accept", filetype);
            inputElem.click();
            inputElem.onchange = () => {
              let file = inputElem.files[0]; //获取文件信息

              // 所有都转成base64文件流,来自官方文档https://www.tiny.cloud/docs/configure/file-image-upload/#file_picker_callback
              let reader = new FileReader();
              reader.readAsDataURL(file);
              reader.onload = function () {
                // Note: Now we need to register the blob in TinyMCEs image blob
                // registry. In the next release this part hopefully won't be
                // necessary, as we are looking to handle it internally.
                let id = "blobid" + new Date().getTime();
                let blobCache = tinymce.activeEditor.editorUpload.blobCache;
                let base64 = reader.result.split(",")[1];
                let blobInfo = blobCache.create(id, file, base64);
                blobCache.add(blobInfo);

                // call the callback and populate the Title field with the file name
                callback(blobInfo.blobUri(), { title: file.name });
              };
            };
          },
        },
      }
    );

    watch(() => state.isHid, (newVal, oldVal) => {
      state.isAllChecked = false
      if (!newVal) {
        state.page = 1
        getTableData()
      } else {
        state.tableData = []
      }
    })

    watch(() => state.checkList, (newVal, oldVal) => {
      if (state.checkList.length != state.tableData.length) {
        state.isAllChecked = false
      }
    })

    function getTableData() {
      const obj = {
        page: state.page,
        size: state.size,
        messageMode: 5,
      }
      api.messageSearch(obj).then(res => {
        if (res.code == '200') {
          state.tableData = res.data.records
          state.total = res.data.total
        } else {
          warningDeal(res.msg)
        }
      }).catch(err => {
        console.log(err)
      })
    }

    function getShopList() {
      api.shopList().then(res => {
        if (res.code == '200') {
          state.shopOptions = res.data
        } else {
          warningDeal(res.msg)
        }
      }).catch(err => {
        console.log(err)
      })
    }

    function mousewheel(e) {
      if (detailDialogRef.value.dialogFormVisible) return
      let down = e.wheelDelta ? e.wheelDelta < 0 : e.detail > 0
      if (down && state.myScrollTop == 0) {
        state.isHid = false
      } else if (!state.isHid && !down) {
        state.isHid = true
      }
    }

    function hisMsgMousewheel(e) {
      let down = e.wheelDelta ? e.wheelDelta < 0 : e.detail > 0
      if (state.myScrollTop == 0 && !down) {
        state.isHid = true
      }
    }

    function hisMsgScroll(e) {
      state.myScrollTop = e.target.scrollTop
    }

    function addMsgScroll(e) {
      state.myScrollTop = e.target.scrollHeight -
        e.target.scrollTop -
        e.target.clientHeight
    }

    function submitHandle() {
      dialogFormRef.value.validate((valid, fields) => {
        if (valid) {
          const obj = {
            title: state.dialogForm.title || '',
            messageContent: state.dialogForm.messageContent || '',
            messageType: state.dialogForm.messageType || '',
            shopIds: state.dialogForm.shopIds || '',
            expireTime: (state.dialogForm.expireTime && state.dialogForm.expireTime.getTime()) || '',
          }
          api.messageSysRelease(obj).then(res => {
            if (res.code == '200') {
              successDeal(res.msg)
              setTimeout(() => {
                state.dialogForm.messageContent = ''
              }, 0);
              dialogFormRef.value.resetFields()
            } else {
              warningDeal(res.msg)
            }
          }).catch(err => {
            console.log(err)
          })
        }
      })
    }

    function tableCheckChange(e, data) {
      data.isChecked = e
      if (e) {
        state.checkList.push(data)
      } else {
        state.checkList = state.checkList.filter(item => item.messageId != data.messageId)
      }
    }

    function handleCurrentChange(e) {
      state.page = e
      getTableData()
    }

    function handleSizeChange(e) {
      state.size = e
      getTableData()
    }

    function lookDetail(data) {
      detailDialogRef.value.dialogShow(data)
    }

    function allChange(e) {
      state.tableData.map(item => {
        tableCheckChange(e, item)
      })
    }

    function moreSXSC(i) {
      state.isSXSC = i
      let title = ''
      let msg = ''
      if (i == 1) {
        //失效
        title = '消息失效提示'
        msg = '是否确认将选中消息失效？'
        confirmPassRef.value.dialogShow(title, msg)
      } else {
        //删除
        title = '消息删除提示'
        msg = '是否确认将选中消息删除？'
        confirmPassRef.value.dialogShow(title, msg)
      }
    }

    function getMessageIds(list) {
      const myArr = []
      list && list.map(item => {
        if (!item.messageId) return
        myArr.push(item.messageId)
      })
      return myArr
    }

    function SXSCHandle() {
      const obj = {
        messageIds: getMessageIds(state.checkList)
      }
      if (state.isSXSC == 1) {
        api.messageSysExpire(obj).then(res => {
          if (res.code == '200') {
            successDeal(res.msg)
            state.checkList = []
            getTableData()
          } else {
            warningDeal(res.msg)
          }
        }).catch(err => {
          console.log(err)
        })
      } else {
        api.messageSysDelete(obj).then(res => {
          if (res.code == '200') {
            successDeal(res.msg)
            state.checkList = []
            getTableData()
          } else {
            warningDeal(res.msg)
          }
        }).catch(err => {
          console.log(err)
        })
      }
    }

    onMounted(() => {
      let winHeight = getWindowWidthAndHeight()
      state.tableHeight = winHeight.windowHeight - 200
      getShopList()
    })

    return {
      ...toRefs(state),
      ...toRefs(tiny),
      dialogFormRef,
      confirmPassRef,
      editorRef,
      mousewheel,
      hisMsgMousewheel,
      hisMsgScroll,
      submitHandle,
      addMsgScroll,
      tableCheckChange,
      handleCurrentChange,
      handleSizeChange,
      getDateTime,
      detailDialogRef,
      lookDetail,
      allChange,
      getTableData,
      moreSXSC,
      SXSCHandle,
    }
  }
}
</script>

<style lang="scss" scoped>
.msg-box {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  .add-box {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    padding: 20px;
    overflow-y: auto;
    .add-content {
      margin-top: 20px;
      overflow-y: auto;
      box-sizing: border-box;
      padding: 0 5px;
    }
  }
  .his-box {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    box-sizing: border-box;
    padding: 20px;
    transition: top 0.3s;
    z-index: 9;
    .his-content {
      margin-top: 20px;
      overflow-y: auto;
      box-sizing: border-box;
      padding: 0 5px;
      > .table-box {
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        padding-bottom: 35px;
        .table-item {
          display: flex;
          align-items: center;
          box-sizing: border-box;
          padding: 10px;
          transition: all 0.3s;
          cursor: pointer;
          background-color: rgba($color: #75787f, $alpha: 0.1);
          &:not(:first-of-type) {
            margin-top: 10px;
          }
          &:hover {
            background-color: rgba($color: #1266ff, $alpha: 0.3);
          }
          .msg-content {
            width: 100%;
            font-size: 14px;
            > div:last-of-type {
              font-size: 12px;
              color: #75787f;
              margin-top: 10px;
              width: 100%;
              display: flex;
              align-items: center;
            }
          }
        }
      }
    }
    .his-footer {
      display: flex;
      align-items: center;
    }
  }
}
.title-box {
  .title-text {
    font-size: 16px;
    font-weight: bold;
  }
}
.isHid {
  top: 100vh !important;
}
.expireType1,
.expireType0 {
  font-size: 12px;
  display: inline-block;
  box-sizing: border-box;
  padding: 2px 5px;
  color: #ffffff;
  border-radius: 5px;
  margin-left: 10px;
}
.expireType1 {
  background-color: #1266ff;
}
.expireType0 {
  background-color: #75787f;
}
</style>